package com.nosql.db.core.wal;

import com.nosql.db.core.modul.Document;
import java.io.Serializable;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

public class WALEntry implements Serializable {
    public String getCollection() {
        return collection;
    }

    public enum Operation { PUT, DELETE, CREATE_COLLECTION, UPDATE }

    // 新增数据存储字段
    private final Map<String, Object> data;
    private final Operation operation;
    private final String documentId;
    private final long timestamp;
    private final String collection;
    // 保留文档字段（兼容旧日志）
    private Document document;

    // PUT操作新构造函数（推荐）
    public WALEntry(Operation operation,String collection, String documentId, Map<String, Object> data) {
        if (!(operation == Operation.PUT || operation == Operation.UPDATE)) {
            throw new IllegalArgumentException("该构造函数仅适用于PUT操作");
        }
        this.operation = operation;
        this.documentId = documentId;
        this.data = new ConcurrentHashMap<>(data);
        this.timestamp = System.currentTimeMillis();
        this.collection = collection;
    }

    // DELETE操作构造函数
    public WALEntry(Operation operation,String collection, String documentId) {
        if (!(operation == Operation.DELETE || operation == Operation.CREATE_COLLECTION)) {
            throw new IllegalArgumentException("该构造函数仅适用于DELETE操作");
        }
        this.operation = operation;
        this.documentId = documentId;
        this.data = Collections.emptyMap();
        this.timestamp = System.currentTimeMillis();
        this.collection = collection;
    }



    // 兼容旧日志的构造函数（逐步淘汰）
    @Deprecated
    public WALEntry(Operation operation,String collection, Document document) {
        this.operation = operation;
        this.document = document;
        this.documentId = document.getId();
        this.data = document.getData();
        this.timestamp = System.currentTimeMillis();
        this.collection = collection;
    }

    // 增强数据访问方法
    public Document getDocument() {
        if (document == null && (operation == Operation.PUT || operation == Operation.UPDATE)) {
            document = new Document(collection, data);
            document.setId(documentId);
        }
        return document;
    }

    // 新增文本序列化方法
    public String toTxtFormat() {
        StringBuilder sb = new StringBuilder();
        sb.append(operation).append("|")
                .append(documentId).append("|")
                .append(timestamp).append("|")
                .append("__collection=").append(collection);

        if (operation == Operation.DELETE) {
            sb.append("|__tombstone=true"); // 标记为墓碑
        } else if (operation == Operation.PUT || operation == Operation.UPDATE) {
            sb.append(",").append(convertDataToText(data));
        }
        return sb.toString();
    }


    // 修改数据转换方法使用完整数据集
    private String convertDataToText(Map<String, Object> dataToConvert) {
        return dataToConvert.entrySet().stream()
                .map(e -> e.getKey().replace("=", "\\=") + "=" +
                        e.getValue().toString().replace(",", "\\,"))
                .collect(Collectors.joining(","));
    }

    // 新增文本解析方法
    public static WALEntry parseFromTxt(String line) {
        System.out.println("[WAL] Parsing: " + line);
        String[] parts = line.split("\\|", 4);
        if (parts.length < 4) {
            throw new IllegalArgumentException("Invalid WAL entry: " + line);
        }

        Operation op = Operation.valueOf(parts[0]);
        String docId = parts[1];
        long timestamp = Long.parseLong(parts[2]);
        String dataPart = parts[3];
        Map<String, Object> data = new HashMap<>();
        String collection = null;
        boolean isTombstone = false;

        // 处理数据部分
        String[] entries = dataPart.split("(?<!\\\\),");
        for (String entry : entries) {
            String[] kv = entry.split("(?<!\\\\)=", 2);
            if (kv.length == 2) {
                String key = kv[0].replace("\\=", "=").replace("\\,", ",");
                String value = kv[1].replace("\\=", "=").replace("\\,", ",");

                // 捕获集合名称
                if ("__collection".equals(key)) {
                    collection = value;
                }
                // 捕获墓碑标记
                else if ("__tombstone".equals(key)) {
                    isTombstone = "true".equals(value);
                }
                // 其他数据字段
                else {
                    data.put(key, value);
                }
            }
        }

        if (collection == null) {
            throw new IllegalArgumentException("Missing collection in WAL entry");
        }

        // 处理墓碑标记
        if (isTombstone) {
            return new WALEntry(Operation.DELETE, collection, docId);
        }

        if (op == Operation.PUT || op == Operation.UPDATE) {
            return new WALEntry(op, collection, docId, data);
        } else {
            return new WALEntry(op, collection, docId);
        }
    }


    public Map<String, Object> getData() {
        return Collections.unmodifiableMap(data);
    }

    // 其他getters保持不变
    public Operation getOperation() { return operation; }
    public String getDocumentId() { return documentId; }
    public long getTimestamp() { return timestamp; }
}
